#include "gd32f30x.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "DevicesSPI.h"


void vSPI0Init(void)
{
    spi_parameter_struct spi_init_struct = {0};

    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);

    /* SPI0 GPIO config:SCK, MOSI */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
    /* SPI0 GPIO config:MISO */
    gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
    /* SPI0 GPIO config:NSS */
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

    SET_SPI0_NSS_HIGH();


    /* SPI0 parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_8;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI0, &spi_init_struct);

    /* SPI enable */
    spi_enable(SPI0);
}

void vSPI1Init(void)
{
    spi_parameter_struct spi_init_struct = {0};

    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI1);

    /* SPI0 GPIO config:SCK, MOSI */
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
    /* SPI0 GPIO config:MISO */
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
    /* SPI0 GPIO config:NSS */
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);

    SET_SPI1_NSS_HIGH();


    /* SPI0 parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_32;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI1, &spi_init_struct);

    /* SPI enable */
    spi_enable(SPI1);
}

uint8_t ucSPIWriteReadByte(uint32_t uiSpiPeriph, uint8_t ucByte)
{
    while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
    spi_i2s_data_transmit(uiSpiPeriph, ucByte);

    while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_RBNE));
    ucByte = spi_i2s_data_receive(uiSpiPeriph);

    return ucByte;
}

int8_t cSPIWriteDatas(uint32_t uiSpiPeriph, void *pvBuff, int32_t iLength)
{
    uint8_t *pucBuffer = pvBuff;
    int8_t cError = 0;

    if(pvBuff == NULL)
        return -1;

    while((iLength--) > 0)
    {
        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
        spi_i2s_data_transmit(uiSpiPeriph, *pucBuffer++);

        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_RBNE));
        spi_i2s_data_receive(uiSpiPeriph);
    }

    return cError;
}

int8_t cSPIReadDatas(uint32_t uiSpiPeriph, void *pvBuff, int32_t iLength)
{
    uint8_t *pucBuffer = pvBuff;
    int8_t cError = 0;

    if(pvBuff == NULL)
        return -1;

    while((iLength--) > 0)
    {
        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
        spi_i2s_data_transmit(uiSpiPeriph, 0xFFFF);

        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_RBNE));
        *pucBuffer++ = spi_i2s_data_receive(uiSpiPeriph);
    }

    return cError;
}
